package org.jeecg.modules.data.util;

import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.handler.CellWriteHandler;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.holder.WriteTableHolder;
import lombok.Data;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.util.CellRangeAddress;

import java.util.List;

@Data
public class GroupedMergeStrategy implements CellWriteHandler {
    private int[] mergeColumnIndex;
    private int mergeRowIndex;

    public GroupedMergeStrategy() {
    }

    public GroupedMergeStrategy(int mergeRowIndex, int[] mergeColumnIndex) {
        this.mergeRowIndex = mergeRowIndex;
        this.mergeColumnIndex = mergeColumnIndex;
    }

    @Override
    public void beforeCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Row row, Head head, Integer columnIndex, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellCreate(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {

    }

    @Override
    public void afterCellDispose(WriteSheetHolder writeSheetHolder, WriteTableHolder writeTableHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer integer, Boolean aBoolean) {
        //当前行
        int curRowIndex = cell.getRowIndex();
        //当前列
        int curColIndex = cell.getColumnIndex();

        if (curRowIndex > mergeRowIndex) {
            for (int i = 0; i < mergeColumnIndex.length; i++) {
                if (curColIndex == mergeColumnIndex[i]) {
                    mergeWithPrevRow(writeSheetHolder, cell, curRowIndex, curColIndex);
                    break;
                }
            }
        }
    }

    /**
     * 当前单元格向上合并
     *
     * @param writeSheetHolder
     * @param cell 当前单元格
     * @param curRowIndex 当前行
     * @param curColIndex 当前列
     */
    private void mergeWithPrevRow(WriteSheetHolder writeSheetHolder, Cell cell, int curRowIndex, int curColIndex) {
        // 如果是第一行，直接返回（没有上一行）
        if (curRowIndex == 0) {
            return;
        }

        // 获取当前行和上一行的当前列数据
        Object curColData = getCellValue(cell);
        Cell preCell = cell.getSheet().getRow(curRowIndex - 1).getCell(curColIndex);
        Object preColData = getCellValue(preCell);

        // 1. 检查当前列数据是否相同
        if (!isEqual(curColData, preColData)) {
            return;
        }

        // 2. 如果当前列不是第一列，检查前面所有列
        if (curColIndex > 0) {
            Row curRow = cell.getSheet().getRow(curRowIndex);
            Row preRow = cell.getSheet().getRow(curRowIndex - 1);

            // 从第一列(0)检查到当前列的前一列(curColIndex-1)
            for (int col = 0; col < curColIndex; col++) {
                Cell curColCell = curRow.getCell(col);
                Cell preColCell = preRow.getCell(col);

                Object curColValue = getCellValue(curColCell);
                Object preColValue = getCellValue(preColCell);

                // 如果任一列数据不同，直接返回不合并
                if (!isEqual(curColValue, preColValue)) {
                    return;
                }
            }
        }

        // 3. 执行合并操作（只有所有检查都通过才会执行）
        Sheet sheet = writeSheetHolder.getSheet();
        List<CellRangeAddress> mergeRegions = sheet.getMergedRegions();
        boolean isMerged = false;

        for (int i = 0; i < mergeRegions.size() && !isMerged; i++) {
            CellRangeAddress cellRangeAddr = mergeRegions.get(i);
            if (cellRangeAddr.isInRange(curRowIndex - 1, curColIndex)) {
                sheet.removeMergedRegion(i);
                cellRangeAddr.setLastRow(curRowIndex);
                sheet.addMergedRegion(cellRangeAddr);
                isMerged = true;
            }
        }

        if (!isMerged) {
            CellRangeAddress cellRangeAddress = new CellRangeAddress(
                    curRowIndex - 1,
                    curRowIndex,
                    curColIndex,
                    curColIndex
            );
            sheet.addMergedRegion(cellRangeAddress);
        }
    }

    /**
     * 获取单元格的值
     * @param cell 单元格
     * @return 单元格的值（字符串或数字）
     */
    private Object getCellValue(Cell cell) {
        if (cell == null) {
            return ""; // 空单元格返回空字符串
        }
        return cell.getCellTypeEnum() == CellType.STRING ?
                cell.getStringCellValue() :
                cell.getNumericCellValue();
    }

    /**
     * 比较两个值是否相等（处理null情况）
     * @param obj1 值1
     * @param obj2 值2
     * @return 是否相等
     */
    private boolean isEqual(Object obj1, Object obj2) {
        if (obj1 == null && obj2 == null) {
            return true;
        }
        if (obj1 == null || obj2 == null) {
            return false;
        }
        return obj1.equals(obj2);
    }
}
